using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Reflection;

namespace ParsingLogic.ContextXSD
{
    public class CTX_XSD_Builder
    {
        
        public string GetContextXSD(System.Collections.Generic.Dictionary<string,string> DLLs, string XMLNamespaceFile)
        {
            //Build the XSD
            StringBuilder _str = new StringBuilder();
            _str.Append(@"<xs:schema xmlns:b=""http://schemas.microsoft.com/BizTalk/2003"" xmlns=""http://BAMWriter/v1/SystemContextProperties"" targetNamespace=""http://BAMWriter/v1/SystemContextProperties"" xmlns:xs=""http://www.w3.org/2001/XMLSchema""><xs:element name=""ContextProperties""><xs:complexType><xs:sequence>");
            foreach (System.Collections.Generic.KeyValuePair<string,string> entry in DLLs)
            {
                ArrayList _newArray = new ArrayList();
                SortedDictionary<string,string> _newProperties = getContextProperties(entry.Value);

                _str.Append(buildXML(entry.Key, _newProperties));
            }
            _str.Append("</xs:sequence></xs:complexType></xs:element></xs:schema>");
            
            //Try this again
            List<Types.ContextLibrary> _library = new List<ParsingLogic.Types.ContextLibrary>();
            foreach (System.Collections.Generic.KeyValuePair<string, string> entry in DLLs)
            {
                ArrayList _newArray = new ArrayList();
                SortedDictionary<string, string> _newProperties = getContextProperties(entry.Value);
                List<Types.ContextLibrary> _libItems = new List<ParsingLogic.Types.ContextLibrary>();
                _libItems = buildNamespaceFile(entry.Key, _newProperties);
                foreach (Types.ContextLibrary uniqueLibrary in _libItems)
                {
                    _library.Add(uniqueLibrary);
                }
                
            }

            ////Build the metadata xml document for later use by the Dispatcher
            //CTXLibrary _lib = new CTXLibrary();
            //CTXLibraryCTXLib[] _libItems = null;
            //List<CTXLibraryCTXLib> _holder = new List<CTXLibraryCTXLib>();
                        
            //foreach (System.Collections.Generic.KeyValuePair<string, string> entry in DLLs)
            //{
            //    ArrayList _newArray = new ArrayList();
            //    SortedDictionary<string, string> _newProperties = getContextProperties(entry.Value);
            //    _libItems = buildNamespaceFile(entry.Key, _newProperties);
            //    foreach (CTXLibraryCTXLib lib in _libItems)
            //    {
            //        _holder.Add(lib);
            //    }
            //}
            
            //_lib.CTXLib = _holder.ToArray();
            
            //Serialize this out to the XML File
            //Write out the ActivityMetadata.xml file

                System.Xml.Serialization.XmlSerializer objXmlSer = new System.Xml.Serialization.XmlSerializer(typeof(List<Types.ContextLibrary>));
            System.Xml.XmlTextWriter _metaDataWriter = new System.Xml.XmlTextWriter(System.IO.Path.Combine(XMLNamespaceFile,"MetaData_ContextNamespaces.xml"), null);
            objXmlSer.Serialize(_metaDataWriter, _library);
            _metaDataWriter.Flush();
            _metaDataWriter.Close();
            
            return _str.ToString();
        }
        private static SortedDictionary<string,string> getContextProperties(string IOPath)
        {
            Assembly GlobalProps = Assembly.LoadFile(IOPath);
            Type[] _types = GlobalProps.GetTypes();
            Hashtable _htRoots = new Hashtable();
            Hashtable _htChildren = new Hashtable();
            
            SortedDictionary<string, string> _retVals = new SortedDictionary<string, string>();
            
            ArrayList _alOfTypes = new ArrayList();
            ArrayList _alSortableFullNames = new ArrayList();
            foreach (Type _type in _types)
            {
                if (_type.BaseType.Name == "MessageContextPropertyBase")
                {
                    Microsoft.XLANGs.BaseTypes.MessageContextPropertyBase _ctx = (Microsoft.XLANGs.BaseTypes.MessageContextPropertyBase)System.Activator.CreateInstance(_type);
                    _retVals.Add(_type.FullName + "#" + _ctx.Name.Name, _ctx.Name.Namespace);
                    //Console.WriteLine(_ctx.Name.Name + " - " + _ctx.Type.ToString());
                }
                if (_type.BaseType.Name == "MessageDataPropertyBase")
                {
                    Microsoft.XLANGs.BaseTypes.MessageDataPropertyBase _ctx = (Microsoft.XLANGs.BaseTypes.MessageDataPropertyBase)System.Activator.CreateInstance(_type);
                    _retVals.Add(_type.FullName + "#" + _ctx.Name.Name, _ctx.Name.Namespace);
                }
            }
            
            
            //_alSortableFullNames.Sort();
            return _retVals;
        }
        //private static CTXLibraryCTXLib[] buildNamespaceFile(string ElementName, SortedDictionary<string, string> _includedProps)
        //{
        //    SortedDictionary<string, string> _parents = new SortedDictionary<string, string>();
        //    StringBuilder _str = new StringBuilder();
            
        //    ArrayList _holder = new ArrayList();
        //    int ctr = 0;
        //    foreach (KeyValuePair<string, string> str in _includedProps)
        //    {
        //        CTXLibraryCTXLib _retVal = new CTXLibraryCTXLib();
        //        string[] splitter1 = str.Key.Split('#');
        //        string[] splitter2 = splitter1[0].Split('.');
        //        if (!_parents.ContainsKey(splitter2[0]))
        //        {
        //            _parents.Add(splitter2[0], str.Value);
        //            _retVal.ContextName = splitter2[0];
        //            _retVal.ContextNameSpace = str.Value;
        //            _retVal.ElementName = ElementName;
        //            _holder.Add(_retVal);
        //            ctr ++;
                    
        //        }
        //        else
        //        {

        //        }
                
        //    }
        //    CTXLibraryCTXLib[] _retArray = new CTXLibraryCTXLib[ctr];
        //    int i = 0;
        //    foreach(CTXLibraryCTXLib item in _holder)
        //    {
        //        _retArray[i] = item;
        //        i++;
            
        //    }
        //    return _retArray;
        //}
        private static List<Types.ContextLibrary> buildNamespaceFile(string ElementName, SortedDictionary<string, string> _includedProps)
        {
            SortedDictionary<string, string> _parents = new SortedDictionary<string, string>();
            StringBuilder _str = new StringBuilder();
            List<Types.ContextLibrary> _returnValues = new List<ParsingLogic.Types.ContextLibrary>();

            ArrayList _holder = new ArrayList();
            int ctr = 0;
            foreach (KeyValuePair<string, string> str in _includedProps)
            {
                Types.ContextLibrary _retVal = new Types.ContextLibrary();
                string[] splitter1 = str.Key.Split('#');
                string[] splitter2 = splitter1[0].Split('.');
                if (!_parents.ContainsKey(splitter2[0]))
                {
                    _parents.Add(splitter2[0], str.Value);
                    _retVal.ContextName = splitter2[0];
                    _retVal.ContextNamespace = str.Value;
                    _retVal.ElementName = ElementName;
                    _returnValues.Add(_retVal);
                }
                else
                {

                }

            }
            return _returnValues;
        }
       
        private static string buildXML(string ElementName, SortedDictionary<string,string> _includedProps)
        {
            SortedDictionary<string, string> _parents = new SortedDictionary<string, string>();
            StringBuilder _str = new StringBuilder();
            //_str.Append(@"<xs:element name=""" + ElementName + @""" namespace=""" + ElementNameSpace + @"""><xs:complexType><xs:sequence>");

            _str.Append(@"<xs:element name=""" + ElementName + @"""><xs:complexType><xs:sequence>");
            string lastParent = "";
            foreach (KeyValuePair<string,string> str in _includedProps)
            {
                
                string[] splitter1 = str.Key.Split('#');
                string[] splitter2 = splitter1[0].Split('.');
                if (!_parents.ContainsKey(splitter2[0]))
                {
                    //if this isnt the first parent then we need to close the last one.
                    if (lastParent.Length != 0)
                    {
                        _str.Append(@"</xs:sequence></xs:complexType>");
                        _str.Append("</xs:element>");
                    }
                    lastParent = splitter2[0];
                    _parents.Add(splitter2[0], str.Value);
                    _str.Append(@"<xs:element name=""" + splitter2[0] + @""">");
                    _str.Append(@"<xs:complexType><xs:sequence>");
                }
                else
                {

                }
                _str.Append(@"<xs:element name=""" + splitter1[0] + @"""  type=""xs:string"" />");

            }
            //_str.Append("--------------------------------------------------------------------------------");
            _str.Append(@"</xs:sequence></xs:complexType>");
            _str.Append("</xs:element>");
            _str.Append("</xs:sequence></xs:complexType></xs:element>");
            return _str.ToString();
        }
    }
}
